using Mapster;
using Microsoft.AspNetCore.Http;
using SqlSugar;
using QiAdmin.Core;
using QiAdmin.Core.Services.Log;
using QiAdmin.Core.Services.Token;
using QiAdmin.Core.Utils;
using QiAdmin.Entity;
using QiAdmin.Model.Dtos;
using QiAdmin.Model.Dtos.Input;
using QiAdmin.Model.Dtos.Output;
using QiAdmin.Model.System.Models;
using QiAdmin.Repository.Repository;
using QiAdmin.Service.IService;
using ICacheService = QiAdmin.Core.Services.Cache.ICacheService;

namespace QiAdmin.Service.Service
{
    /// <summary>
    /// TSysDept Services
    /// </summary>
    public class TSysDeptService : BaseService<TSysDept, TSysDept_IN, TSysDept_OUT>, ITSysDeptService
    {
        readonly TSysDeptRepository _tSysDeptRepository;
        readonly TSysUserRepository _tSysUserRepository;
        public TSysDeptService(ILogService logService,
            ITokenService tokenService, ICacheService cacheService, IHttpContextAccessor httpContextAccessor, TSysDeptRepository tSysDeptRepository, TSysUserRepository tSysUserRepository) : base(logService, tokenService, cacheService, httpContextAccessor.HttpContext)
        {
            _tSysDeptRepository = tSysDeptRepository;
            _tSysUserRepository = tSysUserRepository;
        }

        #region 增删改查-自动生成

        /// <summary>
        /// 创建默认条件
        /// </summary>
        /// <returns></returns>
        public Expressionable<TSysDept> CreateExp()
        {
            var exp = Expressionable.Create<TSysDept>();
            exp.AndIF(Token.UserDept != App.StaticData.SystemDept, t => t.Id != App.StaticData.SystemDept);
            return exp;
        }

        /// <summary>
        /// 新增单条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult Add(TSysDept_IN input)
        {
            var model = input.Adapt<TSysDept>();
            int Id = _tSysDeptRepository.InsertReturnIdentity(model);
            AddDeptCache();
            return CommonResult.Convert(Id > 0);
        }

        /// <summary>
        /// 新增多条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult AddRange(List<TSysDept_IN> input)
        {
            var list = input.Adapt<List<TSysDept>>();
            var result = _tSysDeptRepository.InsertRange(list);
            AddDeptCache();
            return CommonResult.Convert(result);
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult Edit(TSysDept_IN input)
        {
            var exp = CreateExp();
            exp.And(t => t.Id == input.Id);
            var model = input.Adapt<TSysDept>();
            var result = _tSysDeptRepository.UpdateAndIgnore(model, exp.ToExpression());
            AddDeptCache();
            return CommonResult.Convert(result);
        }

        /// <summary>
        /// 获取单条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<TSysDept_OUT> Get(TSysDept_IN input)
        {
            var exp = CreateExp();
            exp.And(t => t.Id == input.Id);

            var result = _tSysDeptRepository.GetFirst(exp.ToExpression()).Adapt<TSysDept_OUT>();
            return new CommonResult<TSysDept_OUT>(result);
        }

        /// <summary>
        /// 分页获取
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<PageOutput<TSysDept_OUT>> GetPageList(TSysDept_IN input)
        {
            var exp = CreateExp();

            exp.AndIF(input.StartQueryTime != DateTime.MinValue, t => t.SysCreateTime >= input.StartQueryTime.Date);
            exp.AndIF(input.EndQueryTime != DateTime.MinValue, t => t.SysCreateTime < input.EndQueryTime.Date.AddDays(1));

            exp.AndIF(!string.IsNullOrEmpty(input.Name), t => t.Name.Contains(input.Name));

            PageOutput<TSysDept_OUT> pageOutput = new PageOutput<TSysDept_OUT>();
            PageModel pageModel = new() { PageIndex = input.PageIndex, PageSize = input.PageSize };
            pageOutput.Data = _tSysDeptRepository.GetPageList(exp.ToExpression(), pageModel).Adapt<List<TSysDept_OUT>>();
            pageOutput.DataCount = pageModel.TotalCount;

            return new CommonResult<PageOutput<TSysDept_OUT>>(pageOutput);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult Remove(TSysDept_IN input)
        {
            var exp = CreateExp();
            exp.And(t => t.Id == input.Id);

            var result = _tSysDeptRepository.Delete(exp.ToExpression());
            AddDeptCache();
            return CommonResult.Convert(result);
        }

        /// <summary>
        /// 删除多条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult RemoveRange(List<TSysDept_IN> input)
        {
            var exp = CreateExp();
            exp.And(t => input.Select(s => s.Id).Contains(t.Id));

            var result = _tSysDeptRepository.Delete(exp.ToExpression());
            AddDeptCache();
            return CommonResult.Convert(result);
        }

        #endregion

        /// <summary>
        /// 获取部门数据(树形结构)
        /// </summary>
        /// <returns></returns>
        public CommonResult<List<TreeDept>> GetDepts(TSysDept_IN input)
        {
            var exp = CreateExp();
            exp.AndIF(!string.IsNullOrEmpty(input.Name), t => t.Name.Contains(input.Name));
            var queryable = _tSysDeptRepository.Context.Queryable<TSysDept>().Where(exp.ToExpression()).Select(t => new TreeDept
            {
                ParentId = t.ParentId,
                Id = t.Id,
                Name = t.Name,
                Desc = t.Desc,
                Status = t.Status,
                SysCreateTime = t.SysCreateTime
            });
            if (!string.IsNullOrEmpty(input.Name))
            {
                return new CommonResult<List<TreeDept>>(queryable.ToList());
            }
            else
            {
                return new CommonResult<List<TreeDept>>(queryable.ToTree(s => s.children, s => s.ParentId, 0, s => s.Id));
            }

        }

        /// <summary>
        /// 删除部门数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult RemoveDept(TSysDept_IN input)
        {
            var childCount = _tSysDeptRepository.Count(t => t.ParentId == input.Id);
            if (childCount > 0)
            {
                return CommonResult.Convert(false, "请先删除子级部门");
            }
            var userCount = _tSysUserRepository.Count(t => t.DeptId == input.Id);
            if (userCount > 0)
            {
                return CommonResult.Convert(false, "请先删除该部门下用户");
            }
            var result = _tSysDeptRepository.DeleteById(input.Id);
            AddDeptCache();
            return CommonResult.Convert(result);
        }

        public CommonResult<List<TSysDept_OUT>> GetDeptCache()
        {
            var list = _CacheService.Get<List<TSysDept_OUT>>(App.StaticData.CacheKey_Dept);
            return new CommonResult<List<TSysDept_OUT>>(list);
        }

        public CommonResult AddDeptCache() 
        {
            var roleData = _tSysDeptRepository.GetList();
            _CacheService.Add(App.StaticData.CacheKey_Dept, roleData.Adapt<List<TSysDept_OUT>>());
            return CommonResult.Success;
        }

    }
}
